---------------------------------------------------------------------------------
  -- Design Name : work.UserPkg.GenAdd32 Test Bench
  -- File Name   : GenAdd32.vht
  -- Function    : work.UserPkg.GenAdd32 test bench
  -- Authors     : Mirko Francuski  2006/0225
  --               Milos Mihajlovic 2006/0039
  -- School      : University of Belgrade
  --               School for Electrical Engineering
  --               Department for Computer Engineering and Information Theory
  -- Subject     : VLSI Computer Systems
---------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.TBPkg.all;
use work.UserPkg.all;

entity ExMemAlu32_vhd_tst is
  -- this page is intentionally left blank
end ExMemAlu32_vhd_tst;

architecture ExMemAlu32_arch of ExMemAlu32_vhd_tst is
  -- constants
  -- signals
  signal clk    : std_logic;
  signal c      : std_logic;
  signal v      : std_logic;
  signal z      : std_logic;
  signal n      : std_logic;
  signal in1    : Word32;
  signal in2    : Word32;
  signal res    : Word32;
  signal op     : OpCode;
  
begin
  
  Clock_inst : Clock port map (
    clk => clk
  );
  
  ExMemAlu32_inst : ExMemAlu32 port map (
    -- list connections between master ports and signals
    op      => op,
    n       => n,
    z       => z,
    in1     => in1,
    in2     => in2,
    alu_out => res,
    v       => v,
    c       => c
  );
  
  init : process
  -- variable declarations
  begin
    -- code that executes only once
    wait;                                 -- stop running
  end process init;
  
  always : process
    -- optional sensitivity list
    -- (        )
    -- variable declarations
  begin
    -- code executes for every event on sensitivity list
    report "Testing...";
    wait for DELAY; 
    for clkCount in 0 to 14 loop
      case clkCount mod 15 is
        -- Test #1
        when 0 => 
          op  <= OPC_ADD;
          in1 <= "01101010101010101010101010101010";
          in2 <= "00011000000000000011111111111110";
        -- Test #2
        when 1 => 
          op  <= OPC_ADDI;
          in1 <= "00000000000000000000000000000001";
          in2 <= "11111111111111111111111111111111";
        -- Test #3
        when 2 => 
          op  <= OPC_SUB;
          in1 <= "01101010101010101010101010101010";
          in2 <= "00011000000000000011111111111110";
        -- Test #4
        when 3 =>
          op  <= OPC_SUBI;
          in1 <= "01101010101010101010101010101010";
          in2 <= "00000000000000000011111111111110";
        -- Test #5
        when 4 => 
          op  <= OPC_AND;
          in1 <= "10101010101010101010101010101010";
          in2 <= "11111111111111110000000000000000";
        -- Test #6
        when 5 => 
          op  <= OPC_OR;
          in1 <= "10101010101010101010101010101010";
          in2 <= "11111111111111110000000000000000";
        -- Test #7
        when 6 => 
          op  <= OPC_XOR;
          in1 <= "10101010101010101010101010101010";
          in2 <= "11111111111111110000000000000000";
        -- Test #8
        when 7 =>
          op  <= OPC_NOT;
          in1 <= "00001111000011110000111100001111";
          in2 <= "00000000000000000000000011110000";
        -- Test #9
        when 8 =>
          op  <= OPC_SHL;
          in1 <= "10101010101010101010101010101010";
          in2 <= "00000000000000000000000000000100";
        -- Test #10
        when 9 =>
          op  <= OPC_SHR;
          in1 <= "10101010101010101010101010101010";
          in2 <= "00000000000000000000000000000100";
        -- Test #11
        when 10 =>
          op  <= OPC_SAR;
          in1 <= "10101010101010101010101010101010";
          in2 <= "00000000000000000000000000000100";
        -- Test #12
        when 11 =>
          op  <= OPC_ROL;
          in1 <= "10101010101010101010101010101010";
          in2 <= "00000000000000000000000000000100";
        -- Test #13
        when 12 =>
          op  <= OPC_ROR;
          in1 <= "10101010101010101010101010101010";
          in2 <= "00000000000000000000000000000100";
        -- Test #14
        when 13 =>
          op  <= OPC_MOV;
          in1 <= "10101010101010101111111111111111";
          in2 <= "10101010101010101111111111111111";
        -- Test #15
        when others =>
          op  <= OPC_MOVI;
          in1 <= "00000000000000000111111111111111";
          in2 <= "00000000000000000111111111111111";
      end case;
      wait for 5 ps; -- da ne vrsio pretvaranja u momentu promene vrednosti na ulazu
      report "    INT_MAX = " & integer'image(INT_MAX);
      report "    INT_MIN = " & integer'image(INT_MIN);
      report "    in1 = " & integer'image(to_integer(signed(in1)));
      report "    in2 = " & integer'image(to_integer(signed(in2)));
      report "    out = " & integer'image(to_integer(signed(res)));
      assert v = '0' report "    overflow" severity note;
      report "    in1 (unsigned) = " & hstr(in1);
      report "    in2 (unsigned) = " & hstr(in2);
      report "    out (unsigned) = " & hstr(res);
      assert c = '0' report "    carry" severity note;
      wait for CLOCK_PERIOD - 5 ps;
    end loop;
    
    assert false report "Testing done." severity failure;
    wait;                                 -- stop running
  end process always;
end ExMemAlu32_arch;

configuration ExMemAlu32_vhd_cfg of ExMemAlu32_vhd_tst is 
	for ExMemAlu32_arch
    -- this page is intentionally left blank too
	end for;
end ExMemAlu32_vhd_cfg;